package com.edu.hre.struts.action.pim;

import java.awt.Image;
import java.io.ByteArrayInputStream;
import java.util.Date;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;

import com.edu.hre.common.utils.BeanFinder;
import com.edu.hre.common.utils.ComboBoxInit;
import com.edu.hre.common.utils.CommonUtils;
import com.edu.hre.common.utils.RequestUtils;
import com.edu.hre.common.utils.StringConstants;
import com.edu.hre.db.pojo.HreEmpPicture;
import com.edu.hre.db.pojo.HreEmployee;
import com.edu.hre.db.pojo.HreUser;
import com.edu.hre.db.pojo.HreUserRoleScreen;
import com.edu.hre.db.service.BaseService;
import com.edu.hre.db.sql.pim.EmployeeDAOService;
import com.edu.hre.db.utils.Compare;
import com.edu.hre.struts.form.pim.EmpPersonalDetailUpdateForm;
import com.google.gwt.http.client.Response;

public class EmpPersonalDetailUpdateAction extends Action {

	private static final Logger logger = Logger.getLogger(EmpPersonalDetailUpdateAction.class);
	private static final BaseService baseService = BeanFinder.getBean(BaseService.BEAN_NAME, BaseService.class);
	private static final EmployeeDAOService employeeDAOService = BeanFinder.getBean(EmployeeDAOService.BEAN_NAME, EmployeeDAOService.class);
	private final String ACTION_NAME = "empPersonalDetailUpdate";
	
	public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		CommonUtils.println(CommonUtils.getSourceCodeLocation());
		HreEmployee you = (HreEmployee) request.getSession().getAttribute(RequestUtils.Attribute.EMPLOYEE_INFO);
		
		int id = CommonUtils.getIntParameter("id", request);
		if(id == -1){
			if(you != null && you.getEmpNumber() != null){
				id = you.getEmpNumber();
			}
		}
		if(id != you.getEmpNumber()){
			HreUser tpUser = (HreUser) request.getSession().getAttribute(RequestUtils.Attribute.USER_INFO);
			if (!EmployeeListAction.isAllowedToViewEmployeeList(tpUser, id)) {
				response.sendError(Response.SC_BAD_REQUEST);
				return null;
			}
		}
		
		// Get the authorization of the current user for the specified operations. 
		HreUserRoleScreen userRoleScreen = (HreUserRoleScreen) request.getSession().getAttribute(RequestUtils.Attribute.HreUserRoleScreen);
				
		EmpPersonalDetailUpdateForm beanForm = (EmpPersonalDetailUpdateForm) form;
		beanForm.setUpdatable(userRoleScreen.isCanUpdate());
		beanForm.setIsAddNew(false);
		
		if(request.getParameter("btnUpdate") == null){ 
			EmployeeListAction.setAttributesForRequest(id, request);
			HreEmployee tmp = baseService.getFirstPojo("empNumber", Compare.EQUAL, id, null, null, 0, HreEmployee.class);
			if (tmp == null) {
				initFormBean(beanForm, request);
				beanForm.setMessage(StringConstants.BLANK);
				beanForm.setSuccess(false);
				return mapping.findForward(ACTION_NAME);
			}
			
			beanForm.setEmpNumber(tmp.getEmpNumber());
			beanForm.setEmpFirstname(CommonUtils.normalizeString(tmp.getEmpFirstname()));
			beanForm.setEmpMiddleName(CommonUtils.normalizeString(tmp.getEmpMiddleName()));
			beanForm.setEmpLastname(CommonUtils.normalizeString(tmp.getEmpLastname()));
			beanForm.setIdCardNumber(CommonUtils.normalizeString(tmp.getEmpIdCardNum()));
			beanForm.setIdCardLocationIssued(CommonUtils.normalizeString(tmp.getEmpIdCardPlace()));
			beanForm.setIdCardDateIssued(CommonUtils.dateToString(tmp.getEmpIdCardDate()));
			beanForm.setGender((short) CommonUtils.normalizeShort(tmp.getEmpGender()));
			beanForm.setMarriedStatus(CommonUtils.normalizeString(tmp.getEmpMaritalStatus()));
			beanForm.setNationality(CommonUtils.normalizeInteger(tmp.getNationCode()));
			beanForm.setDateOfBirth(CommonUtils.dateToString(tmp.getEmpBirthday()));
			beanForm.setNickName(CommonUtils.normalizeString(tmp.getEmpNickName()));
			beanForm.setMilitaryService(CommonUtils.normalizeString(tmp.getEmpMilitaryService()));
			
			initFormBean(beanForm, request);
			beanForm.setMessage(StringConstants.BLANK);
			beanForm.setSuccess(false);
			return mapping.findForward(ACTION_NAME);
		}
		
		EmployeeListAction.setAttributesForRequest(beanForm.getEmpNumber(), request);
		
		String message = validateForm(beanForm);
		if(!StringUtils.isBlank(message)){
			beanForm.setMessage(message);
			beanForm.setSuccess(false);
			initFormBean(beanForm, request);
			return mapping.findForward(ACTION_NAME);
		}

		HreEmployee tmp = baseService.getFirstPojo("empNumber", Compare.EQUAL, beanForm.getEmpNumber(), null, null, 0, HreEmployee.class);
		if (tmp == null) {
			initFormBean(beanForm, request);
			beanForm.setMessage(StringConstants.BLANK);
			beanForm.setSuccess(false);
			return mapping.findForward(ACTION_NAME);
		}

		tmp.setEmpFirstname(CommonUtils.normalizeString(beanForm.getEmpFirstname()));
		tmp.setEmpMiddleName(CommonUtils.normalizeString(beanForm.getEmpMiddleName()));
		tmp.setEmpLastname(CommonUtils.normalizeString(beanForm.getEmpLastname()));
		tmp.setEmpIdCardNum(CommonUtils.normalizeString(beanForm.getIdCardNumber()));
		tmp.setEmpIdCardPlace(CommonUtils.normalizeString(beanForm.getIdCardLocationIssued()));
		tmp.setEmpIdCardDate(CommonUtils.stringToDate(CommonUtils.normalizeString(beanForm.getIdCardDateIssued())));
		tmp.setEmpGender(beanForm.getGender());
		tmp.setEmpMaritalStatus(CommonUtils.normalizeString(beanForm.getMarriedStatus()));
		tmp.setNationCode(beanForm.getNationality());
		tmp.setEmpBirthday(CommonUtils.stringToDate(CommonUtils.normalizeString(beanForm.getDateOfBirth())));
		tmp.setEmpNickName(CommonUtils.normalizeString(beanForm.getNickName()));
		tmp.setEmpMilitaryService(CommonUtils.normalizeString(beanForm.getMilitaryService()));
		tmp.setDateModified(new Date());

		boolean status = baseService.saveOrUpdate(tmp);
		if (!status) {
			beanForm.setMessage(StringConstants.UPDATE_FAILURE_MESSAGE);
			beanForm.setSuccess(false);
			return mapping.findForward(ACTION_NAME);
		}
		
		// Change user name if necessary.
		String newUsername = employeeDAOService.getCandidateUsername(
				CommonUtils.normalizeString(beanForm.getEmpFirstname()),
				CommonUtils.normalizeString(beanForm.getEmpMiddleName()),
				CommonUtils.normalizeString(beanForm.getEmpLastname()));
		
		HreUser tmpUser = baseService.getFirstPojo("empNumber", Compare.EQUAL, tmp.getEmpNumber(), null, null, 0, HreUser.class);
		if (tmpUser == null || tmpUser.getUserName() == null || !tmpUser.getUserName().contains(newUsername)) {
			newUsername = employeeDAOService.getNewUsername(
					CommonUtils.normalizeString(beanForm.getEmpFirstname()),
					CommonUtils.normalizeString(beanForm.getEmpMiddleName()),
					CommonUtils.normalizeString(beanForm.getEmpLastname()));
			if (tmpUser != null && !"root".equalsIgnoreCase(tmpUser.getUserName())
					&& !"admin".equalsIgnoreCase(tmpUser.getUserName())
					&& !newUsername.equals(tmpUser.getUserName())) {
				tmpUser.setUserName(newUsername);
				tmp.setMainUsername(newUsername);
				baseService.saveOrUpdate(tmpUser);
				baseService.saveOrUpdate(tmp);
			}
		}

		FormFile myFile = beanForm.getImage();
		if(myFile != null && StringUtils.isNotBlank(myFile.getFileName())){
			HreEmpPicture picture = baseService.getFirstPojo("empNumber", Compare.EQUAL, tmp.getEmpNumber(), null, null, 0, HreEmpPicture.class);
			if(picture == null){
				picture = new HreEmpPicture();
			}
			picture.setEpicType(myFile.getContentType());
			picture.setEmpNumber(tmp.getEmpNumber());
			picture.setEpicFileSize(String.valueOf(myFile.getFileSize()));
			picture.setDateModified(new Date());
			picture.setDateCreated(new Date());
			picture.setEpicFilename(myFile.getFileName());
			picture.setEpicPicture(myFile.getFileData());
			String w = null;
			String h = null;
			try {
				Image imgTemp = ImageIO.read(new ByteArrayInputStream(myFile.getFileData()));
				w = imgTemp.getWidth(null) + StringConstants.BLANK;
				h = imgTemp.getHeight(null) + StringConstants.BLANK;				
			} catch (Exception e) {
				CommonUtils.println(e.getMessage());
			}
			picture.setEpicFileWidth(w);
			picture.setEpicFileHeight(h);
			baseService.saveOrUpdate(picture);
		}

		beanForm.setMessage("Personal details have been updated successfully!");
		beanForm.setSuccess(true);
		return mapping.findForward(ACTION_NAME);
	}
	
	private void initFormBean(EmpPersonalDetailUpdateForm beanForm, HttpServletRequest request) {

		beanForm.setAllMaritalStatuses(ComboBoxInit.getAllMaritalStatuses());
		beanForm.setAllNationalities(ComboBoxInit.getAllNationalities(false));
		beanForm.setAllGenders(ComboBoxInit.getAllGenders(true));
	}
	
	private String validateForm (EmpPersonalDetailUpdateForm beanForm) {
		
		if(StringUtils.isBlank(CommonUtils.normalizeString(beanForm.getEmpFirstname()))){
			return "First name cannot be blank!";
		}

		if(StringUtils.isBlank(CommonUtils.normalizeString(beanForm.getEmpLastname()))){
			return "Last name cannot be blank!";
		}
		
		if (CommonUtils.checkLaterThanToday(beanForm.getIdCardDateIssued(), -1, -1, -1)) {
			return "Issued date of the ID Card must not be in the future!";
		}
		
		if (CommonUtils.checkLaterThanToday(beanForm.getDateOfBirth(), -1, -1, -1)) {
			return "Date of birth must not be in the future!";
		}
		
		FormFile myFile = beanForm.getImage();
		if(myFile != null && StringUtils.isNotBlank(myFile.getFileName())){
			if(myFile.getFileSize() > 2097152){
				return "Image file size is too big! (< 2MB required)";
			} else if(!"image/jpeg".equalsIgnoreCase(myFile.getContentType())){
				return "Invalid file type! Only JPEG or PNG files are accepted!";
			}
		}

		return StringConstants.BLANK;
	}
}
